package yyy.ab.modules.quartz.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.ApiOperation;
import org.quartz.JobDataMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import yyy.ab.common.core.BaseController;
import yyy.ab.common.core.ResultBean;
import yyy.ab.common.utils.DateUtils;
import yyy.ab.common.utils.SnowFlakeUtil;
import yyy.ab.modules.quartz.QuartzJobManage;
import yyy.ab.modules.quartz.entity.QuartzJob;
import yyy.ab.modules.quartz.entity.QuartzJobInfo;
import yyy.ab.modules.quartz.service.QuartzJobService;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/system/job")
public class QuartzJobController extends BaseController {

    @Autowired
    private QuartzJobService quartzJobService;

    /**
     * 引用任务调度管理器
     */
    @Autowired
    private QuartzJobManage quartzJobManage;

    /**
     * 页面跳转
     */
    @RequestMapping
    public ModelAndView jump() {
        ModelAndView view = new ModelAndView();
        view.setViewName("system/job/index");
        return view;
    }

    /**
     * 分页查询
     *
     * @param params
     * @return
     */
    @GetMapping("/findPage")
    public Object findPage(@RequestParam Map<String, Object> params) {
        IPage<QuartzJob> page = quartzJobService.findPage(params);
        if (page.getRecords() != null && page.getRecords().size() > 0) {
            for (QuartzJob quartzJob : page.getRecords()) {
                initJobOtherParam(quartzJob);
            }
        }
        return jsonForTable(page);
    }

    /**
     * 添加任务
     *
     * @param jobTitle       任务标题
     * @param jobClassName   任务类名
     * @param parameter      任务参数
     * @param description    任务备注
     * @param cronExpression 表达式
     */
    @RequestMapping("/add")
    public Object jobAdd(String jobTitle, String jobClassName, String cronExpression, String parameter, String description) throws Exception {
        String jobName = String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
        QuartzJobInfo quartzJobInfo = QuartzJobInfo.builder()
                .jobTitle(jobTitle)
                .jobClassName(jobClassName)
                .jobName(jobName)
                .cronExpresstion(cronExpression)
                .parameter(parameter)
                .description(description)
                .build();
        ResultBean status = quartzJobManage.jobAdd(quartzJobInfo);
        return status;
    }

    /**
     * 修改任务
     *
     * @param jobName        任务标识
     * @param jobGroup       任务分组
     * @param triggerState   任务状态
     * @param jobTitle       任务标题
     * @param jobClassName   任务类名
     * @param parameter      任务参数
     * @param description    任务备注
     * @param cronExpression 表达式
     */
    @RequestMapping("/edit")
    public Object jobAdd(String jobName, String jobGroup, String triggerState, String jobTitle, String jobClassName, String cronExpression, String parameter, String description) throws Exception {
        ResultBean resultBean = quartzJobManage.jobDelete(jobName, jobGroup);
        if (!resultBean.getSuccess()) return resultBean;
        jobName = String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
        QuartzJobInfo quartzJobInfo = QuartzJobInfo.builder()
                .jobTitle(jobTitle)
                .jobClassName(jobClassName)
                .jobName(jobName)
                .cronExpresstion(cronExpression)
                .parameter(parameter)
                .description(description)
                .triggerState(triggerState)
                .build();
        ResultBean status = quartzJobManage.jobAdd(quartzJobInfo);
        return status;
    }

    /**
     * 修改定时任务时间
     *
     * @param triggerName
     * @param triggerGroupName
     * @param newTime
     * @return
     */
    @RequestMapping("/modifyJobTime")
    public Object modifyJobTime(String triggerName, String triggerGroupName, String newTime) {
        ResultBean status = quartzJobManage.modifyJobTime(triggerName, triggerGroupName, DateUtils.getCronExpression(new Date(Long.parseLong(newTime))));
        return status;
    }

    /**
     * 任务删除
     *
     * @param jobName
     * @param jobGroupName
     * @throws Exception
     */
    @RequestMapping("/delete")
    public Object jobDelete(String jobName, String jobGroupName) throws Exception {
        ResultBean status = quartzJobManage.jobDelete(jobName, jobGroupName);
        return status;
    }

    /**
     * 任务删除
     *
     * @param ids
     * @return
     */
    @PostMapping("/batchDel")
    public Object jobDeletes(@RequestBody String[] ids) throws Exception {
        if (ids != null && ids.length > 0) {
            for (String id : ids) {
                String[] strings = id.split("#");
                quartzJobManage.jobDelete(strings[0], strings[1]);
            }
        }
        return ResultBean.success("批量删除成功！");
    }

    /**
     * 任务暂停
     *
     * @param jobName
     * @param jobGroupName
     * @throws Exception
     */
    @RequestMapping("/pause")
    public Object jobPause(String jobName, String jobGroupName) throws Exception {
        ResultBean status = quartzJobManage.jobPause(jobName, jobGroupName);
        return status;
    }

    /**
     * 任务继续
     *
     * @param jobName
     * @param jobGroupName
     * @throws Exception
     */
    @RequestMapping("/resume")
    public Object jobResume(String jobName, String jobGroupName) throws Exception {
        ResultBean status = quartzJobManage.jobResume(jobName, jobGroupName);
        return status;
    }

    /**
     * 任务重启
     *
     * @param jobName
     * @param jobGroupName
     * @param cronExpression
     * @throws Exception
     */
    @RequestMapping("/reschedule")
    public Object jobReschedule(String jobName, String jobGroupName, String cronExpression) throws Exception {
        ResultBean status = quartzJobManage.jobReschedule(jobName, jobGroupName, cronExpression);
        return status;
    }

    /**
     * 任务立即执行
     *
     * @param jobName
     * @param jobGroupName
     * @return
     * @throws Exception
     */
    @RequestMapping("/trigger")
    public Object jobTrigger(String jobName, String jobGroupName) throws Exception {
        jobName = jobName.replace("'", "");
        jobGroupName = jobGroupName.replace("'", "");
        ResultBean status = quartzJobManage.jobTrigger(jobName, jobGroupName);
        return status;
    }

    private void initJobOtherParam(QuartzJob quartzJob) {
        if (quartzJob.getJobData() != null) {
            JobDataMap toObject = toObject(quartzJob.getJobData());
            if (toObject != null && toObject.containsKey("jobTitle")) {
                quartzJob.setJobTitle(toObject.getString("jobTitle"));
            }
            if (toObject != null && toObject.containsKey("parameter")) {
                quartzJob.setParameter(toObject.getString("parameter"));
            }
            if (toObject != null && toObject.containsKey("description")) {
                quartzJob.setDescription(toObject.getString("description"));
            }
        }
    }

    /**
     * 将byte数组转化为Object对象
     *
     * @return
     */
    private JobDataMap toObject(byte[] bytes) {
        Object object = null;
        try {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);// 创建ByteArrayInputStream对象
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);// 创建ObjectInputStream对象
            object = objectInputStream.readObject();// 从objectInputStream流中读取一个对象
            byteArrayInputStream.close();// 关闭输入流
            objectInputStream.close();// 关闭输入流
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (JobDataMap) object;// 返回对象
    }
}
